package com.chiancloud.shield.common.params;

import com.beust.jcommander.Parameter;
import com.chiancloud.shield.core.exception.BadCommandArgumentsException;
import com.chiancloud.shield.core.exception.ErrorStrings;
import org.apache.hadoop.fs.Path;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;


public abstract class AbstractActionArgs extends ArgOps implements Arguments {


  protected static final Logger log =
    LoggerFactory.getLogger(AbstractActionArgs.class);


  protected AbstractActionArgs() {
  }

  /**
   * URI of the filesystem
   */
  @Parameter(names = {ARG_FILESYSTEM, ARG_FILESYSTEM_LONG},
             description = "Filesystem URI",
             converter = URIArgumentConverter.class)
  public URI filesystemURL;

  @Parameter(names = {ARG_BASE_PATH},
             description = "Slider base path on the filesystem",
             converter =  PathArgumentConverter.class)
  public Path basePath;



  @Parameter
  public final List<String> parameters = new ArrayList<>();



  public String getClusterName() {
    return (parameters.isEmpty()) ? null : parameters.get(0);
  }



  @Parameter(names = ARG_DEFINE, arity = 1, description = "Definitions")
  public final List<String> definitions = new ArrayList<>();


  @Parameter(names = {ARG_SYSPROP}, arity = 1,
             description = "system properties in the form name value" +
                           " These are set after the JVM is started.")
  public final List<String> sysprops = new ArrayList<>(0);


  @Parameter(names = {ARG_MANAGER_SHORT, ARG_MANAGER},
             description = "hostname:port of the YARN resource manager")
  public String manager;


  @Parameter(names = ARG_DEBUG, description = "Debug mode")
  public boolean debug = false;


  public int getMinParams() {
    return 1;
  }


  public abstract String getActionName() ;


  public int getMaxParams() {
    return getMinParams();
  }

  public void validate() throws BadCommandArgumentsException {
    
    int minArgs = getMinParams();
    int actionArgSize = parameters.size();
    if (minArgs > actionArgSize) {
      throw new BadCommandArgumentsException(
        ErrorStrings.ERROR_NOT_ENOUGH_ARGUMENTS + getActionName());
    }
    int maxArgs = getMaxParams();
    if (maxArgs == -1) {
      maxArgs = minArgs;
    }
    if (actionArgSize > maxArgs) {
      String message = String.format("%s for action %s: limit is %d but saw %d",
                                     ErrorStrings.ERROR_TOO_MANY_ARGUMENTS,
                                     getActionName(), maxArgs,
                                     actionArgSize);
      log.error(message);
      int index = 1;
      for (String actionArg : parameters) {
        log.error("[{}] \"{}\"", index++, actionArg);
      }
      throw new BadCommandArgumentsException(message);
    }
  }

  @Override
  public String toString() {
    return super.toString() + ": " + getActionName();
  }
}
